package com.lanyou.esb.cook.proxy.redis.proxy.base;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Response;
import redis.clients.jedis.exceptions.JedisException;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.lanyou.esb.cook.proxy.redis.JedisPoolUtils;
import com.lanyou.esb.cook.proxy.redis.proxy.StrJedisProxy;

/**
 * String数据类型,操作Redis代理类基类
 * 
 * @author Davey.wu
 */
public abstract class BaseStrJedisProxy<T> extends BaseJedisProxy<T> implements
		StrJedisProxy<T> {
	protected static final String STRING_SET_RESULT = "OK";

	private int timeOut;
	private String prefix;

	@Override
	public T get(String key) throws JsonParseException, JsonMappingException,
			IOException {
		String value = "";
		Jedis jedis = JedisPoolUtils.getJedis();
		if (jedis == null) {
			return null;
		}
		boolean broken = false;
		try {
			value = jedis.get(key);
		} catch (Exception e) {
			broken = true;
		} finally {
			JedisPoolUtils.returnRes(jedis, broken);
		}
		if (StringUtils.isBlank(value)) {
			return null;
		}
		return fromJson(value);
	}

	@Override
	public List<T> get(List<String> keys) throws JsonParseException,
			JsonMappingException, IOException {
		if (keys == null || keys.isEmpty()) {
			return null;
		}
		List<T> result = null;
		Jedis jedis = JedisPoolUtils.getJedis();
		if (jedis == null) {
			return null;
		}
		boolean broken = false;
		List<Response<String>> responses = new ArrayList<>(keys.size());
		try {
			Pipeline pipe = jedis.pipelined();
			for (String key : keys) {
				responses.add(pipe.get(key));
			}
			pipe.sync();
		} catch (Exception e) {
			broken = true;
		} finally {
			JedisPoolUtils.returnRes(jedis, broken);
		}
		if (responses.isEmpty()) {
			return null;
		}
		result = new ArrayList<>(responses.size());
		for (Response<String> response : responses) {
			String value = response.get();
			if (StringUtils.isBlank(value)) {
				continue;
			}
			// 将JSON字符串转换成JAVA对象
			result.add(fromJson(value));
		}
		return result;
	}

	@Override
	public void loadAll(List<T> list) throws JedisException,
			JsonProcessingException {
		if (list == null || list.isEmpty()) {
			return;
		}
		Jedis jedis = JedisPoolUtils.getJedis();
		if (jedis == null) {
			return;
		}
		boolean broken = false;
		try {
			Pipeline p = jedis.pipelined();
			for (T t : list) {
				p.setex(this.getKeyFromObject(t), timeOut, this.toJson(t));
			}
			p.sync();
		} catch (Exception e) {
			broken = true;
		} finally {
			JedisPoolUtils.returnRes(jedis, broken);
		}
	}

	@Override
	public long setex(String key, T value) throws JedisException,
			JsonProcessingException {
		long result = 0;
		Jedis jedis = JedisPoolUtils.getJedis();
		if (jedis == null) {
			return 0;
		}
		boolean broken = false;
		try {
			String setResult = jedis.setex(key, timeOut, toJson(value));
			if (STRING_SET_RESULT.equalsIgnoreCase(setResult)) {
				result = 1;
			}
		} catch (Exception e) {
			broken = true;
		} finally {
			JedisPoolUtils.returnRes(jedis, broken);
		}
		return result;
	}

	@Override
	public void incrByFloat(String key, float value) {
		Jedis jedis = JedisPoolUtils.getJedis();
		if (jedis == null) {
			return;
		}
		boolean broken = false;
		try {
			jedis.incrByFloat(key, value);
		} catch (Exception e) {
			broken = true;
		} finally {
			JedisPoolUtils.returnRes(jedis, broken);
		}
	}

	@Override
	public void incrBy(String key, long value) {
		Jedis jedis = JedisPoolUtils.getJedis();
		if (jedis == null) {
			return;
		}
		boolean broken = false;
		try {
			jedis.incrBy(key, value);
		} catch (Exception e) {
			broken = true;
		} finally {
			JedisPoolUtils.returnRes(jedis, broken);
		}
	}

	@Override
	public boolean exists(String key) {
		boolean result = false;
		Jedis jedis = JedisPoolUtils.getJedis();
		if (jedis == null) {
			return false;
		}
		boolean broken = false;
		try {
			result = jedis.exists(key);
		} catch (Exception e) {
			broken = true;
		} finally {
			JedisPoolUtils.returnRes(jedis, broken);
		}
		return result;
	}

	public int getTimeOut() {
		return timeOut;
	}

	public void setTimeOut(int timeOut) {
		this.timeOut = timeOut;
	}

	public String getPrefix() {
		return prefix;
	}

	public void setPrefix(String prefix) {
		this.prefix = prefix;
	}
}
